"""
通用接口类

这个模块定义了项目的对外接口，只暴露用户真正需要的方法。
具体的实现分散在各个子模块中。
"""

from typing import Dict, Any, Optional
import os
import shutil
import logging
from .imagequality.sliding_window_classifier import SlidingWindowClassifierImpl
from .detectdark.dark_detector import DarkDetectorImpl
from .detectblur.blur_detector import BlurDetectorImpl
from .segmentationanalyzer.segmentation_analyzer import SegmentationAnalyzerImpl
from .classifier.classifier import ClassifierImpl
from .segmenter.segmenter import SegmenterImpl


def get_optimal_device() -> str:
    """
    自动获取最优设备
    
    优先选择CUDA，如果不可用则使用CPU
    
    Returns:
        str: 设备名称 ('cuda' 或 'cpu')
    """
    try:
        import torch
        if torch.cuda.is_available():
            device = 'cuda'
            print(f"检测到CUDA设备，使用GPU加速")
        else:
            device = 'cpu'
            print(f"未检测到CUDA设备，使用CPU")
    except ImportError:
        device = 'cpu'
        print(f"PyTorch未安装，使用CPU")
    
    return device


def prepare_output_directory(output_dir: str, clear_existing: bool = True) -> bool:
    """
    准备输出目录
    
    如果目录不存在则创建，如果存在且clear_existing为True则清空目录内容
    
    Args:
        output_dir (str): 输出目录路径
        clear_existing (bool): 是否清空已存在的目录内容，默认为True
        
    Returns:
        bool: 操作是否成功
    """
    try:
        if os.path.exists(output_dir):
            if clear_existing:
                print(f"输出目录已存在，正在清空: {output_dir}")
                # 清空目录内容
                for filename in os.listdir(output_dir):
                    file_path = os.path.join(output_dir, filename)
                    try:
                        if os.path.isfile(file_path) or os.path.islink(file_path):
                            os.unlink(file_path)
                        elif os.path.isdir(file_path):
                            shutil.rmtree(file_path)
                    except Exception as e:
                        print(f"删除文件失败 {file_path}: {e}")
                        return False
            else:
                print(f"输出目录已存在: {output_dir}")
        else:
            print(f"创建输出目录: {output_dir}")
            os.makedirs(output_dir, exist_ok=True)
        
        return True
    except Exception as e:
        print(f"准备输出目录失败: {e}")
        return False


class SlidingWindowClassifier:
    """
    滑窗分类器 - 对外接口
    
    这是用户直接使用的类，提供滑窗检测功能。
    具体的实现委托给imagequality模块中的实现类。
    
    主要方法:
    - detect_blur_single: 检测单张图片中的模糊区域
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 window_size: int = 224,
                 stride: int = 224,
                 blur_class_id: int = 0,
                 confidence_threshold: float = 0.5):
        """
        初始化滑窗分类器
        
        Args:
            model_path (str): 分类模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            window_size (int): 滑窗大小，默认224
            stride (int): 滑窗步长，默认224
            blur_class_id (int): 模糊类别ID，默认0
            confidence_threshold (float): 置信度阈值，默认0.5
        """
        # 创建实现实例
        self._impl = SlidingWindowClassifierImpl(
            model_path=model_path,
            device=device,
            window_size=window_size,
            stride=stride,
            blur_class_id=blur_class_id,
            confidence_threshold=confidence_threshold
        )
    
    def detect_blur_single(self, image, output_path: Optional[str] = None) -> Dict[str, Any]:
        """
        检测单张图片中的模糊区域
        
        Args:
            image: 图像数据，可以是图像路径(str)或PIL Image对象
            output_path (str, optional): 输出图片路径，如果提供则保存带标注的图片
            
        Returns:
            Dict[str, Any]: 检测结果，包含模糊区域坐标和置信度
        """
        return self._impl.detect_blur_single(image, output_path)
    

    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()


class DarkDetector:
    """
    暗区检测器 - 对外接口
    
    这是用户直接使用的类，提供基于分割模型的暗区检测功能。
    具体的实现委托给detectdark模块中的实现类。
    
    主要方法:
    - detect_dark_single: 检测单张图片中的暗区区域
    - detect_dark_batch: 批量检测目录中的图片暗区
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 dark_class_id: int = 1,
                 confidence_threshold: float = 0.5,
                 area_threshold: int = 400000):
        """
        初始化暗区检测器
        
        Args:
            model_path (str): 分割模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            dark_class_id (int): 暗区类别ID，默认1
            confidence_threshold (float): 置信度阈值，默认0.5
            area_threshold (int): 面积阈值，默认400000像素点，大于此值认为有黑边
        """
        # 创建实现实例
        self._impl = DarkDetectorImpl(
            model_path=model_path,
            device=device,
            dark_class_id=dark_class_id,
            confidence_threshold=confidence_threshold,
            area_threshold=area_threshold
        )
    
    def detect_dark_single(self, image, output_path: Optional[str] = None) -> Dict[str, Any]:
        """
        检测单张图片中的暗区区域
        
        Args:
            image: 图像数据，可以是图像路径(str)、PIL Image对象或numpy数组
            output_path (str, optional): 输出图片路径，如果提供则保存带标注的图片
            
        Returns:
            Dict[str, Any]: 检测结果，包含暗区区域信息
        """
        return self._impl.detect_dark_single(image, output_path)
    
    def detect_dark_batch(self, input_dir: str) -> Dict[str, Any]:
        """
        批量检测目录中的图片暗区
        
        Args:
            input_dir (str): 输入图片目录
            
        Returns:
            Dict[str, Any]: 批量检测结果
        """
        return self._impl.detect_dark_batch(input_dir)
    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()
    
    def get_task_type(self) -> str:
        """获取任务类型"""
        return self._impl.get_task_type()


class BlurDetector:
    """
    模糊检测器 - 对外接口
    
    这是用户直接使用的类，提供基于分割模型的模糊检测功能。
    具体的实现委托给detectblur模块中的实现类。
    
    主要方法:
    - detect_blur_single: 检测单张图片中的模糊区域
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 blur_class_id: int = 1,
                 confidence_threshold: float = 0.5):
        """
        初始化模糊检测器
        
        Args:
            model_path (str): 分割模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            blur_class_id (int): 模糊类别ID，默认1
            confidence_threshold (float): 置信度阈值，默认0.5
        """
        # 创建实现实例
        self._impl = BlurDetectorImpl(
            model_path=model_path,
            device=device,
            blur_class_id=blur_class_id,
            confidence_threshold=confidence_threshold
        )
    
    def detect_blur_single(self, image, output_path: Optional[str] = None) -> Dict[str, Any]:
        """
        检测单张图片中的模糊区域
        
        Args:
            image: 图像数据，可以是图像路径(str)、PIL Image对象或numpy数组
            output_path (str, optional): 输出二值图路径，如果提供则保存二值图
            
        Returns:
            Dict[str, Any]: 检测结果，包含模糊区域二值图
        """
        return self._impl.detect_blur_single(image, output_path)
    
    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()
    
    def get_task_type(self) -> str:
        """获取任务类型"""
        return self._impl.get_task_type()


class SegmentationAnalyzer:
    """
    分割模型分析器 - 对外接口
    
    这是用户直接使用的类，提供基于分割模型的类别统计和分析功能。
    具体的实现委托给segmentationanalyzer模块中的实现类。
    
    主要方法:
    - analyze_single: 分析单张图片的类别分布
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 class_names: Optional[list] = None):
        """
        初始化分割模型分析器
        
        Args:
            model_path (str): 分割模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            class_names (list, optional): 类别名称列表，如果为None则使用默认名称
        """
        # 创建实现实例
        self._impl = SegmentationAnalyzerImpl(
            model_path=model_path,
            device=device,
            class_names=class_names
        )
    
    def analyze_single(self, image, target_classes: Optional[list] = None) -> Dict[str, Any]:
        """
        分析单张图片的指定类别分布
        
        Args:
            image: 图像数据，可以是图像路径(str)、PIL Image对象或numpy数组
            target_classes (list, optional): 要计算占比的类别列表，默认为[1, 2]
            
        Returns:
            Dict[str, Any]: 分析结果，包含指定类别的统计信息和二值图
        """
        if target_classes is None:
            target_classes = [1, 2]
        return self._impl.analyze_single(image, target_classes)
    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()
    
    def get_task_type(self) -> str:
        """获取任务类型"""
        return self._impl.get_task_type()

class SlideSegmentationAnalyzer:
    """
    滑窗推理分割模型分析器 - 对外接口
    
    这是用户直接使用的类，提供基于分割模型的类别统计和分析功能。
    具体的实现委托给segmentationanalyzer模块中的实现类。
    
    主要方法:
    - analyze_single: 分析单张图片的类别分布
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 class_names: Optional[list] = None):
        """
        初始化分割模型分析器
        
        Args:
            model_path (str): 分割模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            class_names (list, optional): 类别名称列表，如果为None则使用默认名称
        """
        # 创建实现实例
        self._impl = SegmentationAnalyzerImpl(
            model_path=model_path,
            device=device,
            class_names=class_names
        )
    
    def analyze_single(self, image, target_classes: Optional[list] = None, # —— 新增参数：按需求设置切块与融合方式 ——
        out_x: int = 512,
        out_y: int = 512,
        overlap: float = 0.25,
        pad_val: int = 0,
        fuse_mode: str = "max",  # 可选: "max" 或 "min"
        ) -> Dict[str, Any]:
        """
        分析单张图片的指定类别分布
        
        Args:
            image: 图像数据，可以是图像路径(str)、PIL Image对象或numpy数组
            target_classes (list, optional): 要计算占比的类别列表，默认为[1, 2]
            
        Returns:
            Dict[str, Any]: 分析结果，包含指定类别的统计信息和二值图
        """
        if target_classes is None:
            target_classes = [1, 2]
        return self._impl.slide_analyze_single(image, target_classes,out_x,out_y,overlap,pad_val,fuse_mode)
    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()
    
    def get_task_type(self) -> str:
        """获取任务类型"""
        return self._impl.get_task_type()


class Classifier:
    """
    分类器 - 对外接口
    
    这是用户直接使用的类，提供图像分类功能。
    具体的实现委托给classifier模块中的实现类。
    
    主要方法:
    - classify_single: 分类单张图片
    - classify_batch: 批量分类目录中的图片
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 class_names: Optional[list] = None,
                 logger: Optional[logging.Logger] = None):
        """
        初始化分类器
        
        Args:
            model_path (str): 分类模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            class_names (list, optional): 类别名称列表，如果为None则自动从模型配置中获取
            logger (logging.Logger, optional): 日志记录器，如果提供则使用logger记录日志
        """
        # 创建实现实例
        self._impl = ClassifierImpl(
            model_path=model_path,
            device=device,
            class_names=class_names,
            logger=logger
        )
    
    def classify_single(self, image, output_path: Optional[str] = None) -> Dict[str, Any]:
        """
        分类单张图片
        
        Args:
            image: 图像数据，可以是图像路径(str)、PIL Image对象、numpy数组、OpenCV BGR格式数组或单通道灰度图
            output_path (str, optional): 输出图片路径，如果提供则保存带标注的图片
            
        Returns:
            Dict[str, Any]: 分类结果，包含类别ID、类别名称、置信度等信息
        """
        return self._impl.classify_single(image, output_path)
    
    def classify_batch(self, input_dir: str) -> Dict[str, Any]:
        """
        批量分类目录中的图片
        
        Args:
            input_dir (str): 输入图片目录
            
        Returns:
            Dict[str, Any]: 批量分类结果，每张图片包含分类结果信息
        """
        return self._impl.classify_batch(input_dir)
    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()
    
    def get_task_type(self) -> str:
        """获取任务类型"""
        return self._impl.get_task_type()


class Segmenter:
    """
    分割器 - 对外接口
    
    这是用户直接使用的类，提供图像分割功能。
    具体的实现委托给segmenter模块中的实现类。
    
    主要方法:
    - segment_single: 分割单张图片
    - segment_batch: 批量分割目录中的图片
    - get_model_info: 获取模型信息
    - validate_model: 验证模型是否有效
    """
    
    def __init__(self, 
                 model_path: str, 
                 device: str = 'cpu',
                 class_names: Optional[list] = None,
                 logger: Optional[logging.Logger] = None):
        """
        初始化分割器
        
        Args:
            model_path (str): 分割模型文件路径
            device (str): 推理设备，'cpu' 或 'cuda'
            class_names (list, optional): 类别名称列表，如果为None则自动从模型配置中获取
            logger (logging.Logger, optional): 日志记录器，如果提供则使用logger记录日志
        """
        # 创建实现实例
        self._impl = SegmenterImpl(
            model_path=model_path,
            device=device,
            class_names=class_names,
            logger=logger
        )
    
    def segment_single(self, image, output_path: Optional[str] = None) -> Dict[str, Any]:
        """
        分割单张图片
        
        Args:
            image: 图像数据，可以是图像路径(str)、PIL Image对象、numpy数组、OpenCV BGR格式数组或单通道灰度图
            output_path (str, optional): 输出图片路径，如果提供则保存分割结果图片
            
        Returns:
            Dict[str, Any]: 分割结果，包含分割掩码、类别数量等信息
        """
        return self._impl.segment_single(image, output_path)
    
    def segment_batch(self, input_dir: str) -> Dict[str, Any]:
        """
        批量分割目录中的图片
        
        Args:
            input_dir (str): 输入图片目录
            
        Returns:
            Dict[str, Any]: 批量分割结果，每张图片包含分割结果信息
        """
        return self._impl.segment_batch(input_dir)
    
    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return self._impl.get_model_info()
    
    def validate_model(self) -> bool:
        """验证模型是否有效"""
        return self._impl.validate_model()
    
    def get_task_type(self) -> str:
        """获取任务类型"""
        return self._impl.get_task_type()
